
#include <iostream>
using namespace std;
class Point
{
    friend ostream& operator<<(ostream& out, const Point& p);
public:
    Point(double x = 0, double y = 0);
    ~Point();

    Point& operator=(const Point& p);
    double operator[](int index);
private:
    double x;
    double y;
};

Point::Point(double x, double y)
    : x(x)
    , y(y)
{
    cout << "Point()" << endl;
}

Point::~Point()
{
    cout << "~Point()" << endl;
}

ostream& operator<<(ostream& out, const Point& p)
{
    out << "Point(" << p.x << ", " << p.y << ")" << endl;
    return out;
}

Point& Point::operator=(const Point& p)
{
    cout << "operator=(const Point& p)" << endl;
    this->x = p.x;
    this->y = p.y;
    return *this;
}

double Point::operator[](int index)
{
    if(index < 0 || index > 1)
        throw out_of_range("index out of range, index range in [0, 1].");
    if(0 == index)
        return this->x;
    if(1 == index)
        return this->y;
}

int main()
{
    Point p(3, 4);
    cout << p;

    Point p2;
    // 调用赋值运算符
    p2 = p;

    cout << p2[0] << ", " << p2[1] << endl;

    try
    {
        cout << p2[2] << endl;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
    }

    return 0;
}